import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

public class Menu {

    private HashMap<String, Dish> idmenu = new HashMap<String, Dish>();

    Menu() {

    }

    public HashMap<String, Dish> getIdmenu() {
        return idmenu;
    }

    // 在map中添加dish
    public void addDish(String DID, String name, String price, String tot) {
        if (!Dish.checkID(DID)) {
            System.out.println(MyUtil.ERROR_ID);
        } else if (idmenu.containsKey(DID)) {
            System.out.println(MyUtil.HAVE_DISH);
        } else {
            Dish dish = Dish.newDish(DID, name, price, tot);
            if (dish == null) {
                System.out.println("New dish's attributes input illegal");
            } else if (!MyUtil.checkRepeatName(idmenu, name)) {
                System.out.println("Name repeated");
            } else {
                idmenu.put(DID, dish);
                System.out.println("Add dish success");
            }
        }
    }

    // 根据选项修改菜品选项
    public void changeDish(String option, String id, String str) {

        Dish dish;
        if (!Dish.checkID(id)) {
            System.out.println(MyUtil.ERROR_ID);
            dish = null;
        } else if (!idmenu.containsKey(id)) {
            System.out.println(MyUtil.NO_DISH);
            dish = null;
        } else {
            dish = idmenu.get(id);
        }

        if (dish != null) {
            switch (option) {
            case "-n":
                if (!Dish.checkName(str)) {
                    System.out.println("New name input illegal");
                } else if (!MyUtil.checkRepeatName(idmenu, str)) {
                    System.out.println("New name repeated");
                } else {
                    dish.setName(str);
                    System.out.println("Update dish's name success");
                }
                break;
            case "-t":
                if (!Dish.checkTot(str)) {
                    System.out.println("Change dish's total illegal");
                } else {
                    dish.setTot(Integer.parseInt(str));
                    System.out.println("Update dish's total success");
                }
                break;
            case "-p":
                if (!Dish.checkPrice(str)) {
                    System.out.println("Change dish's price illegal");
                } else {
                    dish.setPrice(Double.parseDouble(str));
                    System.out.println("Update dish's price success");
                }
                break;
            default:
                break;
            }
        }
    }

    // 根据Id搜索dish
    public Dish searchDishByID(String ID) {
        if (!Dish.checkID(ID)) {
            System.out.println("Did input illegal");
            return null;
        } else if (!idmenu.containsKey(ID)) {
            System.out.println(MyUtil.NO_DISH);
            return null;
        } else {
            System.out.println(idmenu.get(ID).toString());
            return idmenu.get(ID);
        }
    }

    // 根据key搜索dish 并返回一个list
    public List<Dish> searchDishByKey(String key) {
        List<Dish> found = MyUtil.getListByKey(idmenu, key);
        printDishList(found, false);
        return found;
    }

    public List<Dish> searchDishByKey(String key, String nStr, String mStr) {
        List<Dish> found = MyUtil.getListByKey(idmenu, key);
        printForDishByPage(found, false, nStr, mStr);
        return found;
    }

    public void printAll() {
        List<Dish> all = new ArrayList<Dish>();
        for (String DishID : idmenu.keySet()) {
            all.add(idmenu.get(DishID));
        }
        printDishList(all, true);

    }

    public void printAll(String nStr, String mStr) {
        List<Dish> all = new ArrayList<Dish>();
        for (String DishID : idmenu.keySet()) {
            all.add(idmenu.get(DishID));
        }
        printForDishByPage(all, true, nStr, mStr);
    }

    // 不按页输出List,all用来判断当list为空时的输出语句
    public static void printDishList(List<Dish> dishList, boolean all) {
        if (dishList.isEmpty()) {
            System.out.println(all ? MyUtil.EMPTY : MyUtil.NO_DISH);
        } else {
            Comparator cmp = new DishComparator();
            Collections.sort(dishList, cmp);
            MyUtil.printComparedDishList(dishList, 0, dishList.size());
        }

    }

    // 按页输出list
    public static void printForDishByPage(List<Dish> dishList, boolean all, String nStr, String mStr) {
        int tot_page = 0, last_page = 0, now_left = 0, now_right = 0, now_page = 0;
        if (dishList.isEmpty()) {
            System.out.println(all ? MyUtil.INNER_PAGE_EMPTY : MyUtil.NO_DISH);
            return;
        } else if (!MyUtil.checkInt(nStr) || !MyUtil.checkNoNegativeInt(mStr) || Integer.parseInt(mStr) == 0) {
            System.out.println(MyUtil.ERROR_PAGE);
            return;
        } else {
            int n = Integer.parseInt(nStr), m = Integer.parseInt(mStr);
            Comparator cmp = new DishComparator();
            Collections.sort(dishList, cmp);
            last_page = dishList.size() % m == 0 ? m : dishList.size() % m;
            tot_page = dishList.size() % m == 0 ? dishList.size() / m : dishList.size() / m + 1;
            if (n < 1) {
                n = 1;
            } else if (n > tot_page) {
                n = tot_page;
            }
            now_page = n;
            MyUtil.printPageDishList(dishList, now_page, last_page, tot_page, m);
            InnerCommand.innerCommand(dishList, now_page, last_page, tot_page, m);
        }
    }
}

class DishComparator implements Comparator<Dish> {
    @Override
    public int compare(Dish dish1, Dish dish2) {
        if (dish1.getDID().charAt(0) == 'H' && (dish2.getDID().charAt(0) == 'C' || dish2.getDID().charAt(0) == 'O')) {
            return -1;
        } else if (dish1.getDID().charAt(0) == 'C' && dish2.getDID().charAt(0) == 'O') {
            return -1;
        } else if (dish1.getDID().charAt(0) == dish2.getDID().charAt(0)) {
            return dish1.getDID().compareTo(dish2.getDID()) > 0 ? 1 : -1;
        } else {
            return 1;
        }
    }
}